package controllers

import (
	"encoding/json"
	"time"

	"git.oschina.net/tinkler/for_kmjxc/models/spaceshop"
	jwt "github.com/dgrijalva/jwt-go"
)

// Operations about Users
type UserController struct {
	HelperController
}

// @Title CreateUser
// @Description create users
// @Param	body		body 	models.spaceshop.User	true		"body for user content"
// @Success 200 {int} models.spaceshop.User.Id
// @Failure 403 body is empty
// @router / [post]
func (u *UserController) Post() {
	var user spaceshop.User
	json.Unmarshal(u.Ctx.Input.RequestBody, &user)
	uid := spaceshop.AddUser(user)
	u.Data["jsonp"] = map[string]int{"uid": uid}
	u.ServeJSONP()
}

// @Title GetAll
// @Description get all Users
// @Success 200 {object} models.spaceshop.User
// @router / [get]
func (u *UserController) GetAll() {
	users := spaceshop.GetAllUsers()
	u.Data["jsonp"] = &users
	u.ServeJSONP()
}

// @Title Get
// @Description get user by uid
// @Param	uid		path 	string	true		"The key for staticblock"
// @Param	ss	header	string	true	"The access_token"
// @Success 200 {object} models.spaceshop.User
// @Failure 403 :uid is empty
// @router /:uid [get]
func (u *UserController) Get() {
	uid := u.GetString(":uid")
	ss := u.Ctx.Request.Header.Get("ss")
	if uid != "" && ss != "" {
		t, err := jwt.Parse(ss, func(*jwt.Token) (interface{}, error) {
			return []byte("hzwy23"), nil
		})
		if err != nil {
			u.Data["json"] = err.Error()
		} else {
			user, err := spaceshop.GetUser(uid)
			if err != nil {
				u.Data["json"] = err.Error()
			} else {

				u.Data["json"] = map[string]interface{}{"authenticated": true, "user": user, "claims": t.Claims}
			}
		}

	}
	u.ServeJSON()
}

// @Title Update
// @Description update the user
// @Param	uid		path 	string	true		"The uid you want to update"
// @Param	body		body 	models.spaceshop.User	true		"body for user content"
// @Success 200 {object} models.spaceshop.User
// @Failure 403 :uid is not int
// @router /:uid [put]
func (u *UserController) Put() {
	uid := u.GetString(":uid")
	if uid != "" {
		var user spaceshop.User
		json.Unmarshal(u.Ctx.Input.RequestBody, &user)
		uu, err := spaceshop.UpdateUser(uid, &user)
		if err != nil {
			u.Data["jsonp"] = map[string]string{"msg": err.Error()}
		} else {
			u.Data["jsonp"] = uu
		}
	}
	u.ServeJSONP()
}

// @Title Delete
// @Description delete the user
// @Param	uid		path 	string	true		"The uid you want to delete"
// @Success 200 {string} delete success!
// @Failure 403 uid is empty
// @router /:uid [delete]
func (u *UserController) Delete() {
	uid := u.GetString(":uid")
	spaceshop.DeleteUser(uid)
	u.Data["jsonp"] = map[string]string{"msg": "delete success!"}
	u.ServeJSONP()
}

// @Title Login
// @Description Logs user into the system
// @Param	email		query 	string	true		"The email for login"
// @Param	password		query 	string	true		"The password for login"
// @Success 200 {string} login success
// @Failure 403 user not exist
// @router /login [get]
func (u *UserController) Login() {

	email := u.GetString("email")
	password := u.GetString("password")
	if user := spaceshop.Login(email, password); user != nil {

		mySigningKey := interface{}([]byte("hzwy23"))
		claims := &jwt.StandardClaims{
			NotBefore: int64(time.Now().Unix() - 1000),
			ExpiresAt: int64(time.Now().Unix() + 1000),
			Issuer:    user.Email,
			Id:        user.ID,
		}
		token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
		ss, err := token.SignedString(mySigningKey)
		if err != nil {
			u.Data["json"] = map[string]interface{}{"error": err.Error()}
		} else {
			u.Data["json"] = map[string]interface{}{"authenticated": true, "access_token": ss}
		}

	} else {
		u.Data["json"] = map[string]interface{}{"authenticated": false, "msg": "email or password not right!"}
	}
	u.ServeAPI()
}

// @Title logout
// @Description Logs out current logged in user session
// @Success 200 {string} logout success
// @router /logout [get]
func (u *UserController) Logout() {
	u.Data["json"] = "logout success"
	u.ServeJSON()
}
